package com.yuanxin.yuanxinkit.utils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LayoutAnimationController;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.facebook.common.executors.UiThreadImmediateExecutorService;
import com.facebook.common.internal.Preconditions;
import com.facebook.common.references.CloseableReference;
import com.facebook.common.util.UriUtil;
import com.facebook.datasource.BaseDataSubscriber;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.drawable.OrientedDrawable;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.image.CloseableStaticBitmap;
import com.facebook.imagepipeline.image.EncodedImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import com.yuanxin.yuanxinkit.R;
import com.yuanxin.yuanxinkit.bean.YuanXinToastBean;


public class FloatViewUtil {

    static ReactApplicationContext mContext;
    static LinearLayout mFloatLayout;
    static WindowManager mWindowManager;
    static TextView textView;
    static TextView txt_title;
    static LinearLayout message_layout;
    static FloatCancelTask floatCancelTask;
    static ImageView imageView;
    static RelativeLayout title_relative;
    static RelativeLayout context_relative;
    static ProgressBar progressBar;
    static Promise userPromise;


    public static void init(ReactApplicationContext context) {
        mContext = context;
    }

    static void setViewAlignment(RelativeLayout.LayoutParams params, int type) {
        switch (type) {
            case 0:
                params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 1);
                break;
            case 1:
                params.addRule(RelativeLayout.CENTER_HORIZONTAL, 1);
                break;
            case 2:
                params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 1);
                break;
        }
    }

    static class ImageCallBackHandler extends Handler {
        /**
         * Subclasses must implement this to receive messages.
         *
         * @param msg
         */
        @Override
        public void handleMessage(Message msg) {
            Drawable drawable = (Drawable) msg.obj;
            if (drawable != null) {
                imageView.setImageDrawable(drawable);
            }
        }
    }


    static void setViewParams(YuanXinToastBean yuanXinToastBean) {
        RelativeLayout.LayoutParams titleParams = (RelativeLayout.LayoutParams) txt_title.getLayoutParams();
        setViewAlignment(titleParams, yuanXinToastBean.getTextAlignment());
        txt_title.setLayoutParams(titleParams);
        txt_title.setTextSize(yuanXinToastBean.getTitleFontSize());
        txt_title.setTextColor(Color.parseColor(yuanXinToastBean.getTextColor()));
        txt_title.setText(yuanXinToastBean.getTitle());

        textView.setText(yuanXinToastBean.getDescription());
        textView.setTextColor(Color.parseColor(yuanXinToastBean.getDesTextColor()));
        textView.setTextSize(yuanXinToastBean.getDesFontSize());
        mFloatLayout.setLayoutAnimation(getAnimationController());
        message_layout.setBackgroundColor(Color.parseColor(yuanXinToastBean.getBackgroundColor()));

        LinearLayout.LayoutParams contextParams = (LinearLayout.LayoutParams) context_relative.getLayoutParams();
        LinearLayout.LayoutParams title_Params = (LinearLayout.LayoutParams) title_relative.getLayoutParams();
        contextParams.setMargins(yuanXinToastBean.getPadding(), yuanXinToastBean.getPadding(), yuanXinToastBean.getPadding(), yuanXinToastBean.getPadding());
        title_Params.setMargins(yuanXinToastBean.getPadding(), yuanXinToastBean.getPadding(), yuanXinToastBean.getPadding(), yuanXinToastBean.getPadding());
        title_relative.setLayoutParams(title_Params);
        context_relative.setLayoutParams(contextParams);
        if (yuanXinToastBean.getStyle() != null && !yuanXinToastBean.getStyle().isEmpty()) {
            switch (yuanXinToastBean.getStyle()) {
                case "Error":
                    imageView.setImageResource(R.drawable.close);
                    break;
                case "Info":
                    imageView.setImageResource(R.drawable.info);
                    break;
                case "Success":
                    imageView.setImageResource(R.drawable.success);
                    break;
                case "Warning":
                    imageView.setImageResource(R.drawable.error);
                    break;
            }
            imageView.setVisibility(View.VISIBLE);
        } else if (yuanXinToastBean.getImageUrl() != null) {
            Uri imageUri = Uri.parse(yuanXinToastBean.getImageUrl());
            boolean doResize = shouldResize(imageUri);
            if (doResize) {
                Drawable drawable = ResourceDrawableIdHelper.getInstance().getResourceDrawable(mContext.getCurrentActivity(), yuanXinToastBean.getImageUrl());
                imageView.setImageDrawable(drawable);
            } else {
                final ImageCallBackHandler imageCallBackHandler = new ImageCallBackHandler();
                ImageRequestBuilder builder = ImageRequestBuilder.newBuilderWithSource(imageUri);
                ImageRequest imageRequest = builder.build();

                ImagePipeline imagePipeline = Fresco.getImagePipeline();
                DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null);
                dataSource.subscribe(new BaseDataSubscriber<CloseableReference<CloseableImage>>() {
                    @Override
                    public void onNewResultImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
                        boolean isFinished = dataSource.isFinished();
                        CloseableReference<CloseableImage> image = dataSource.getResult();
                        if (image != null) {
                            Drawable drawable = getDrawable(image);
                            Message message = new Message();
                            message.obj = drawable;
                            imageCallBackHandler.sendMessage(message);
                        }
                        dataSource.close();
                    }

                    @Override
                    public void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
                        dataSource.close();
                    }

                    @Override
                    public void onProgressUpdate(DataSource<CloseableReference<CloseableImage>> dataSource) {
                    }
                }, UiThreadImmediateExecutorService.getInstance());
            }
            imageView.setVisibility(View.VISIBLE);
        } else
            imageView.setVisibility(View.GONE);
        if (yuanXinToastBean.getShowActivityIndicator())
            progressBar.setVisibility(View.VISIBLE);
        else
            progressBar.setVisibility(View.GONE);
        setViewLayout(yuanXinToastBean);
    }

    static Drawable getDrawable(CloseableReference<CloseableImage> image) {
        Preconditions.checkState(CloseableReference.isValid(image));
        CloseableImage closeableImage = image.get();
        if (closeableImage instanceof CloseableStaticBitmap) {
            CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) closeableImage;
            BitmapDrawable bitmapDrawable = new BitmapDrawable(
                    mContext.getCurrentActivity().getResources(),
                    closeableStaticBitmap.getUnderlyingBitmap());
            if (closeableStaticBitmap.getRotationAngle() == 0 ||
                    closeableStaticBitmap.getRotationAngle() == EncodedImage.UNKNOWN_ROTATION_ANGLE) {
                return bitmapDrawable;
            } else {
                return new OrientedDrawable(bitmapDrawable, closeableStaticBitmap.getRotationAngle());
            }
        } else {
            throw new UnsupportedOperationException("Unrecognized image class: " + closeableImage);
        }
    }

    private static boolean shouldResize(Uri uri) {
        return
                UriUtil.isLocalContentUri(uri) ||
                        UriUtil.isLocalFileUri(uri);
    }

    private static void setViewLayout(YuanXinToastBean yuanXinToastBean) {
        RelativeLayout.LayoutParams textViewParams = (RelativeLayout.LayoutParams) textView.getLayoutParams();
        RelativeLayout.LayoutParams imageViewParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
        RelativeLayout.LayoutParams progressBarParams = (RelativeLayout.LayoutParams) progressBar.getLayoutParams();
        context_relative.setGravity(Gravity.FILL);
        if (yuanXinToastBean.getActivityIndicatorAlignment() == yuanXinToastBean.getDesTextAlignment() &&
                yuanXinToastBean.getDesTextAlignment() == yuanXinToastBean.getImageAlignment()) {
            if (yuanXinToastBean.getDesTextAlignment() == 0) {
                context_relative.setGravity(Gravity.LEFT);
                setViewAlignment(progressBarParams, yuanXinToastBean.getDesTextAlignment());
                imageViewParams.addRule(RelativeLayout.RIGHT_OF, progressBar.getId());
                textViewParams.addRule(RelativeLayout.RIGHT_OF, imageView.getId());
            } else if (yuanXinToastBean.getDesTextAlignment() == 1) {
                context_relative.setGravity(Gravity.CENTER);
                setViewAlignment(textViewParams, yuanXinToastBean.getDesTextAlignment());
                imageViewParams.addRule(RelativeLayout.LEFT_OF, textView.getId());
                progressBarParams.addRule(RelativeLayout.LEFT_OF, imageView.getId());
            } else {
                context_relative.setGravity(Gravity.RIGHT);
                setViewAlignment(textViewParams, yuanXinToastBean.getDesTextAlignment());
                imageViewParams.addRule(RelativeLayout.LEFT_OF, textView.getId());
                progressBarParams.addRule(RelativeLayout.LEFT_OF, imageView.getId());
            }
        } else if (yuanXinToastBean.getActivityIndicatorAlignment() != yuanXinToastBean.getDesTextAlignment()
                && yuanXinToastBean.getActivityIndicatorAlignment() != yuanXinToastBean.getImageAlignment()
                && yuanXinToastBean.getDesTextAlignment() != yuanXinToastBean.getImageAlignment()) {
            setViewAlignment(textViewParams, yuanXinToastBean.getDesTextAlignment());
            setViewAlignment(imageViewParams, yuanXinToastBean.getImageAlignment());
            setViewAlignment(progressBarParams, yuanXinToastBean.getActivityIndicatorAlignment());
        } else {
            if (yuanXinToastBean.getActivityIndicatorAlignment() == yuanXinToastBean.getTextAlignment())
                setGravityView(progressBarParams, textViewParams, yuanXinToastBean.getActivityIndicatorAlignment()
                        , yuanXinToastBean.getDesTextAlignment(), progressBar.getId(), textView.getId());
            else if (yuanXinToastBean.getActivityIndicatorAlignment() == yuanXinToastBean.getImageAlignment())
                setGravityView(progressBarParams, imageViewParams, yuanXinToastBean.getActivityIndicatorAlignment()
                        , yuanXinToastBean.getImageAlignment(), progressBar.getId(), imageView.getId());
            else
                setGravityView(imageViewParams, textViewParams, yuanXinToastBean.getImageAlignment(),
                        yuanXinToastBean.getDesTextAlignment(), imageView.getId(), textView.getId());
        }
        textView.setLayoutParams(textViewParams);
        imageView.setLayoutParams(imageViewParams);
        progressBar.setLayoutParams(progressBarParams);
    }

    private static void setGravityView(RelativeLayout.LayoutParams layoutParams,
                                       RelativeLayout.LayoutParams layoutParams1, int alignment, int alignment1
            , int controlID, int controlID1) {
        switch (alignment) {
            case 0:
                setViewAlignment(layoutParams, alignment);
                layoutParams1.addRule(RelativeLayout.RIGHT_OF, controlID);
                break;
            case 1:
            case 2:
                setViewAlignment(layoutParams1, alignment1);
                layoutParams.addRule(RelativeLayout.LEFT_OF, controlID1);
                break;
        }
    }


    public static void showFloatView(YuanXinToastBean yuanXinToastBean, Promise promise) {
        userPromise = promise;
        if (mFloatLayout == null) {
            WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
            mWindowManager = mContext.getCurrentActivity().getWindowManager();
            wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
            wmParams.format = PixelFormat.RGBA_8888;
            wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
            wmParams.gravity = Gravity.TOP;
            wmParams.x = 0;
            wmParams.y = 0;
            wmParams.width = WindowManager.LayoutParams.MATCH_PARENT;
            wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

            LayoutInflater inflater = mContext.getCurrentActivity().getLayoutInflater();

            mFloatLayout = (LinearLayout) inflater.inflate(R.layout.float_layout, null);
            message_layout = (LinearLayout) mFloatLayout.findViewById(R.id.message_layout);
            txt_title = (TextView) mFloatLayout.findViewById(R.id.txt_title);
            textView = (TextView) mFloatLayout.findViewById(R.id.win_text);
            imageView = (ImageView) mFloatLayout.findViewById(R.id.imageView);
            context_relative = (RelativeLayout) mFloatLayout.findViewById(R.id.context_relative);
            title_relative = (RelativeLayout) mFloatLayout.findViewById(R.id.title_relative);
            progressBar = (ProgressBar) mFloatLayout.findViewById(R.id.progressBar3);
            setViewParams(yuanXinToastBean);

            mWindowManager.addView(mFloatLayout, wmParams);
        } else {
            setViewParams(yuanXinToastBean);
        }
        if (yuanXinToastBean.getForceUserInteraction()) {
            message_layout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    cancelFloatView();
                }
            });
        } else {
            message_layout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    userPromise.resolve("success");
                }
            });
            floatCancelTask = new FloatCancelTask(yuanXinToastBean.getTimeInterval());
            floatCancelTask.execute();
        }
    }

    public static void cancelFloatView() {
        if (mWindowManager != null && mFloatLayout != null)
            mWindowManager.removeView(mFloatLayout);
        mFloatLayout = null;
    }

    static LayoutAnimationController getAnimationController() {
        AnimationSet set = new AnimationSet(true);
        Animation animation = new AlphaAnimation(0.0f, 1.0f);
        animation.setDuration(50);
        set.addAnimation(animation);
        animation = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f
        );
        animation.setDuration(100);
        set.addAnimation(animation);
        return new LayoutAnimationController(set, 0.5f);
    }
}
